package com.example.governmentcrawler.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.governmentcrawler.constant.KeyWordsConst;
import com.example.governmentcrawler.constant.UrlConst;
import com.example.governmentcrawler.service.GetDetailUrlSets;
import com.example.governmentcrawler.utils.FileSup;
import com.example.governmentcrawler.utils.GetDetailId;
import com.example.governmentcrawler.utils.GetRealUrls;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @projectName: GovernmentCrawler
 * @package: com.example.governmentcrawler.service.impl
 * @className: GetDetailUrlSetsImpl
 * @author: xxXPCSC
 * @description: TODO
 * @date: 2024/2/26 18:23
 * @version: 1.0
 **/
@Service
public class GetDetailUrlSetsImpl implements GetDetailUrlSets {

    @Autowired
    private GetDetailId getDetailId;
    @Autowired
    private GetRealUrls getRealUrls;
    @Autowired
    private FileSup fileSup;


    @Override
    public Map<String,Map> getAllUrls() {
        Map<String,Map> urls = new LinkedHashMap<>();

        urls.put("（一）、政府采购网",getDetailUrlSetsForGov());
        urls.put("（二）、湖州市限额发包平台",getDetailUrlSetsForContract());
        urls.put("（三）、湖州市绿色采购服务平台",getDetailUrlSetsForGreenPur());
        urls.put("（四）、湖州公共资源交易网",getDetailUrlSetsForPublicRe());
        urls.put("（五）、湖州市网上中介超市",getDetailUrlSetsForOnLineMarket());

        return urls;
    }

    @Override
    public Map<String, Map> getFilterUrls() {
        Map<String,Map> urls = new LinkedHashMap<>();
        urls.put("（一）、政府采购网",getRealUrls.getRealUrlsForGov(getDetailUrlSetsForGov()));
        urls.put("（二）、湖州市限额发包平台",getRealUrls.getRealUrlsForTwoAndThree(getDetailUrlSetsForContract()));
        urls.put("（三）、湖州市绿色采购服务平台",getRealUrls.getRealUrlsForTwoAndThree(getDetailUrlSetsForGreenPur()));
        urls.put("（四）、湖州公共资源交易网",getRealUrls.getRealUrlsForPublic(getDetailUrlSetsForPublicReHz()));
        urls.put("（五）、湖州市网上中介超市",getRealUrls.getRealUrlsForOnline(getDetailUrlSetsForOnLineMarket()));
        return urls;
    }

    @Override
    public Map<String,Map> getDetailUrlSetsForGov() {
        HashMap<String, Map> result = new HashMap<>();
        for (int i = 0; i < KeyWordsConst.MykeyCode.length; i++) {
            TreeMap<String,String> temp = new TreeMap<>(
                    new Comparator<String>() {
                        @Override
                        public int compare(String obj1, String obj2) {
                            //两个日期相同
                            int startIndex = obj1.indexOf("[");
                            int endIndex = obj1.indexOf("]", startIndex);
                            String prix = obj1.substring(startIndex + 1, endIndex);
                            String later = obj2.substring(startIndex + 1, endIndex);
                            //两个日期相同
                            if (prix.equals(later)) {
                                return obj1.compareTo(obj2); // 若相同时，按照默认顺序插入
                            } else {
                                return later.compareTo(prix); // 降序排序
                            }
                        }
                    });
            if(i==0){
                if(!fileSup.fileExist()||fileSup.ReadForState()==0)
                    //在这里使用 1表示两周的间隔 0表示一天的间隔
                    temp = govInclination(i,1);
                else
                    temp = govInclination(i,0);
                result.put(i==0?"采购意向":"采购项目公告",temp);
                continue;
            }
            for(int j=0;j<KeyWordsConst.MyKeyWord.length;j++){
                JSONObject jsonObject = getDetailId.sendPostForGov(UrlConst.GovUrl, KeyWordsConst.MyKeyWord[j], KeyWordsConst.MykeyCode[i],1,1);
                if (jsonObject==null){
                    System.out.println("Gov接口获取失败");
                    continue;
                }
                if(!jsonObject.getBoolean("success")){
                    System.out.println("Gov当前数据获取失败");
                    continue;
                }
                //获取到数据
                JSONObject data = jsonObject.getJSONObject("result").getJSONObject("data");
                //是否为空 数据为空直接返回
                if(data.getBoolean("empty")) {
                    continue;
                }
                //不为空获得数据数组
                JSONArray dataArray = data.getJSONArray("data");
                for (int h = 0; h < dataArray.size(); h++) {
                    JSONObject item = dataArray.getJSONObject(h);
                    String id = item.getString("articleId");
                    String title = item.getString("title");
                    Timestamp publishDate = (Timestamp)item.getTimestamp("publishDate");
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    String formattedDate = sdf.format(publishDate);
                    temp.put("["+formattedDate+"]    "+title+"  ["+inTitle(title)+"]",UrlConst.GovDetailUrl+id);
                }
            }
            result.put(i==0?"采购意向":"采购项目公告",temp);
        }
        return result;
    }

    @Override
    public Map<String,Map> getDetailUrlSetsForGovFilter(){
        return getRealUrls.getRealUrlsForGov(getDetailUrlSetsForGov());
    }

    @Override
    public Map<String, Map> getDetailUrlSetsForContract() {

        HashMap<String, Map> result = new HashMap<>();
        LocalDate now = LocalDate.now();
        for (int i = 0; i < KeyWordsConst.ContractCoed.length; i++) {
            TreeMap<String,String> temp = new TreeMap<>(
                    new Comparator<String>() {
                        @Override
                        public int compare(String obj1, String obj2) {
                            //两个日期相同
                            int startIndex = obj1.indexOf("[");
                            int endIndex = obj1.indexOf("]", startIndex);
                            String prix = obj1.substring(startIndex + 1, endIndex);
                            String later = obj2.substring(startIndex + 1, endIndex);
                            //两个日期相同
                            if (prix.equals(later)) {
                                return obj1.compareTo(obj2); // 若相同时，按照默认顺序插入
                            } else {
                                return later.compareTo(prix); // 降序排序
                            }
                        }
                    });
            for(int j=0;j<KeyWordsConst.MyKeyWord.length;j++) {
                JSONObject jsonObject = getDetailId.sendPostForContract(UrlConst.ContractDetailUrl, KeyWordsConst.MyKeyWord[j], KeyWordsConst.ContractCoed[i]);
                if (jsonObject==null){
                    System.out.println("Contract接口获取失败");
                    continue;
                }
                if(jsonObject.getJSONObject("custom").getIntValue("count")==0){
                    continue;
                }
                //获取到数据
                JSONArray jsonArray = jsonObject.getJSONObject("custom").getJSONArray("infodata");
                for (int h = 0; h < jsonArray .size(); h++) {
                    JSONObject item = jsonArray .getJSONObject(h);
                    String id = item.getString("infourl");
                    String title = item.getString("title");
                    //定位到两周之内
                    String day = item.getString("infodate");
                    if(inTwoWeeks(day,now)){
                        String s="["+day+"]    "+title+"  ["+inTitle(title)+"]";
                        temp.put(s,UrlConst.ContractPrefixUrl + id);
                    }
                }
            }
            result.put(i==0?"建设工程":"其他工程",temp);
        }
        return result;
    }

    @Override
    public Map<String, Map> getDetailUrlSetsForGreenPur() {
        HashMap<String, Map> result = new HashMap<>();
        LocalDate now = LocalDate.now();
        for (int i = 0; i < KeyWordsConst.GreenPur.length; i++) {
            TreeMap<String,String> temp = new TreeMap<>(
                    new Comparator<String>() {
                        @Override
                        public int compare(String obj1, String obj2) {
                            //两个日期相同
                            int startIndex = obj1.indexOf("[");
                            int endIndex = obj1.indexOf("]", startIndex);
                            String prix = obj1.substring(startIndex + 1, endIndex);
                            String later = obj2.substring(startIndex + 1, endIndex);
                            //两个日期相同
                            if (prix.equals(later)) {
                                return obj1.compareTo(obj2); // 若相同时，按照默认顺序插入
                            } else {
                                return later.compareTo(prix); // 降序排序
                            }
                        }
                    });
            for(int j=0;j<KeyWordsConst.MyKeyWord.length;j++) {
                JSONObject jsonObject = getDetailId.sendPostForGreenPur(UrlConst.GreenPurchaseDetailUrl, KeyWordsConst.MyKeyWord[j], KeyWordsConst.GreenPur[i],15);
                if (jsonObject==null){
                    System.out.println("GreenPur接口获取失败");
                    continue;
                }
                if(jsonObject.getJSONObject("custom").getIntValue("count")==0){
                    continue;
                }
                jsonObject = getDetailId.sendPostForGreenPur(UrlConst.GreenPurchaseDetailUrl, KeyWordsConst.MyKeyWord[j], KeyWordsConst.GreenPur[i],jsonObject.getJSONObject("custom").getIntValue("count")>15?jsonObject.getJSONObject("custom").getIntValue("count"):15);
                if (jsonObject==null){
                    System.out.println("GreenPur接口获取失败");
                    continue;
                }
                if(jsonObject.getJSONObject("custom").getIntValue("count")==0){
                    continue;
                }
                //获取到数据
                JSONArray jsonArray = jsonObject.getJSONObject("custom").getJSONArray("infodata");
                for (int h = 0; h < jsonArray .size(); h++) {
                    JSONObject item = jsonArray .getJSONObject(h);
                    String id = item.getString("infourl");
                    String title = item.getString("title");
                    //定位到两周之内
                    String day = item.getString("infodate");
                    if(inTwoWeeks(day,now)){
                        temp.put("["+day+"]    "+title+"  ["+inTitle(title)+"]",UrlConst.GreenPurchasePrefixUrl+id);
                    }else{
                        break;
                    }
                }
            }
            result.put(i==0?"招标采购":"非招标采购",temp);
        }
        return result;
    }

    @Override
    public Map<String,Map> getDetailUrlSetsForPublicRe() {
        HashMap<String, Map> result = new LinkedHashMap<>();
        for(int i=0;i<2;i++){
            Map<String,String> urls = new LinkedHashMap<>();
            if(i==0){
                for(int j=1;j<=2;j++){
                    JSONObject jsonForPublicRe = getJSONForPublicRe(50, j, i);
                    if(jsonForPublicRe==null){
                        System.out.println("PublicRe接口连接失败");
                        continue;
                    }
                    Map<String, String> urlsSets = getUrlsSets(jsonForPublicRe);
                    urls.putAll(urlsSets);
                }
                result.put(i==0?"工程建设":"其他交易",urls);
                continue;
            }
            JSONObject jsonForPublicRe = getJSONForPublicRe(100, 1, i);
            if(jsonForPublicRe==null){
                System.out.println("PublicRe接口连接失败");
                result.put(i==0?"工程建设":"其他交易",urls);
                continue;
            }
            Map<String, String> urlsSets = getUrlsSets(jsonForPublicRe);
            urls.putAll(urlsSets);
            result.put(i==0?"工程建设":"其他交易",urls);
        }
        return result;
    }

    @Override
    public Map<String, Map> getDetailUrlSetsForPublicReHz() {
        HashMap<String, Map> result = new LinkedHashMap<>();
        LocalDate now = LocalDate.now();
        for(int i=0;i<2;i++){
            Map<String,String> urls = new LinkedHashMap<>();
            JSONObject jsonObject = getDetailId.sendPostForPublicReHz(UrlConst.PublicResourcesUrlHz, KeyWordsConst.PublicRCid[i]);
            if(jsonObject==null){
                System.out.println("PublicReHz接口连接失败");
                result.put(i==0?"工程建设":"其他交易",urls);
                continue;
            }
            JSONArray infolist = jsonObject.getJSONArray("infolist");
            if (infolist.size()==0){
                System.out.println("数据为空");
                continue;
            }
            for (int j=0;j<infolist.size();j++){
                JSONObject item = infolist.getJSONObject(j);
                String day = item.getString("daytime");
                if(!inTwoWeeks(day,now))
                    break;
                String title = item.getString("title");
                String temp_title = inTitle(title);
                if (!temp_title.isEmpty())
                    urls.put("[" + day + "]    " + title + "  [" + temp_title + "]", item.getString("url"));
            }
            result.put(i==0?"工程建设":"其他交易",urls);
        }
        return result;
    }


    @Override
    public Map<String,String> getDetailUrlSetsForOnLineMarket() {
        int count =0;
        int cirle=0;
        Map<String,String> urls = new HashMap<>();
        for(int i=0;i<KeyWordsConst.MyKeyWord.length;i++) {
            cirle=0;
            String s = getDetailId.sendPostForOnLineMarket(UrlConst.OnLineSupermarketDetailUrl, KeyWordsConst.MyKeyWord[i],1);
            if(s==null){
                System.out.println("OnLineMarket接口连接失败");
                continue;
            }
            count = getCount(s);
            urls.putAll(getUrls(s));
            if(count<=10)
                continue;
            cirle=count/10;
            for(int j=1;j<=cirle;j++){
                String temp = getDetailId.sendPostForOnLineMarket(UrlConst.OnLineSupermarketDetailUrl, KeyWordsConst.MyKeyWord[i],j+1);
                if(temp==null){
                    System.out.println("OnLineMarket接口连接失败");
                    continue;
                }
                urls.putAll(getUrls(temp));
            }
        }
        return urls;
    }

    //公共资源
    public JSONObject getJSONForPublicRe(int pagesize,int pageno,int i){
        try {
            return getDetailId.sendPostForPublicRe(UrlConst.PublicResourcesUrl, KeyWordsConst.PublicR[i], pagesize, pageno);
        }catch (Exception e){
            System.out.println(e.toString());
            return null;
        }

    }
    public Map<String,String> getUrlsSets(JSONObject jsonObject){
        LocalDate now = LocalDate.now();
        TreeMap<String,String> urls = new TreeMap<>(
                new Comparator<String>() {
                    @Override
                    public int compare(String obj1, String obj2) {
                        //两个日期相同
                        int startIndex = obj1.indexOf("[");
                        int endIndex = obj1.indexOf("]", startIndex);
                        String prix = obj1.substring(startIndex + 1, endIndex);
                        String later = obj2.substring(startIndex + 1, endIndex);
                        //两个日期相同
                        if (prix.equals(later)) {
                            return obj1.compareTo(obj2); // 若相同时，按照默认顺序插入
                        } else {
                            return later.compareTo(prix); // 降序排序
                        }
                    }
                });
        JSONArray infolist = jsonObject.getJSONArray("infolist");
        for(int j=0;j<infolist.size();j++){
            JSONObject data = infolist.getJSONObject(j);
//            System.out.println(data);
            String title = data.getString("title");
            String day = data.getString("daytime");
           if(inTwoWeeks(day,now)) {
               String s = inTitle(title);
                if(!s.equals(""))
               urls.put("[" + day + "]    " + title + "  [" + s + "]", data.getString("url"));
           }
        }
        return urls;
    }

    //解析得到纪录条数
    public int getCount(String s){
        int count=0;
        Document parse = Jsoup.parse(s);
        Element targetElement = parse.select(":containsOwn(条纪录)").first();

        if(targetElement!=null){
            String targetText = targetElement.text();
            Pattern pattern = Pattern.compile("共(\\d+)条纪录"); // 匹配格式为 "数字条纪录"
            Matcher matcher = pattern.matcher(targetText);
            if (matcher.find()) {
                String numberString = matcher.group(1);
                count=Integer.parseInt(numberString);
            }
        }
        return count;
    }

    //获得url和title 网上超市
    public Map<String,String> getUrls(String html){
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        Document doc = Jsoup.parse(html);
        TreeMap<String,String> urls = new TreeMap<>(
                new Comparator<String>() {
                    @Override
                    public int compare(String obj1, String obj2) {
                        //两个日期相同
                        int startIndex = obj1.indexOf("[");
                        int endIndex = obj1.indexOf("]", startIndex);
                        String prix = obj1.substring(startIndex + 1, endIndex);
                        String later = obj2.substring(startIndex + 1, endIndex);
                        //两个日期相同
                        if (prix.equals(later)) {
                            return obj1.compareTo(obj2); // 若相同时，按照默认顺序插入
                        } else {
                            return later.compareTo(prix); // 降序排序
                        }
                    }
                });
        // 选择特定的表格并获取第二个 <tr> 标签开始的行
        Element table = doc.select("table.sjtable").first();
        if (table != null) {
            Elements rows = table.select("tr");
            if (rows.size() > 1) { // 检查是否存在多个 <tr> 标签
                for (int i = 1; i < rows.size(); i++) {
                    Element row = rows.get(i);
                    Elements cells = row.select("td");
                    if (cells.size() >= 2) {
                        Element firstCell = cells.get(0);
                        Element lastCell = cells.get(cells.size() - 1);
                        if(inTwoWeeks(cells.get(5).text(),currentDate))
                        urls.put("["+cells.get(5).text()+"]    "+firstCell.text()+"  ["+inTitle(firstCell.text())+"]",UrlConst.OnlineSupermarketUrl+lastCell.select("a").first().attr("href"));
                    }
                }
            }
//            else {
//                System.out.println("数据为空，只有一个<tr>标签。");
//            }
        }
//        else {
//            System.out.println("未找到指定的表格");
//        }
        return urls;
    }


    //是否为两周内以内
    public Boolean inTwoWeeks(String task,LocalDate currentDate){
        LocalDate oneMonthsAgo = currentDate.minus(Period.ofDays(14));
        LocalDate parse = LocalDate.parse(task, DateTimeFormatter.ISO_LOCAL_DATE);
        if(parse.isBefore(oneMonthsAgo)){
            return false;
        }
        return true;
    }

    public String inTitle(String title){
        StringBuilder stringBuilder = new StringBuilder();
        for(int i=0;i<KeyWordsConst.MyKeyWord.length;i++){
            if(title.contains(KeyWordsConst.MyKeyWord[i]))
                stringBuilder.append(KeyWordsConst.MyKeyWord[i]+"|");
        }
        String next = stringBuilder.toString();
        if (next.endsWith("|")) {
            next = next.substring(0, next.length() - 1);
        }
        return next;
    }

    public TreeMap<String,String> govInclination(int i,int day){
        TreeMap<String,String> temp = new TreeMap<>(
                new Comparator<String>() {
                    @Override
                    public int compare(String obj1, String obj2) {
                        //两个日期相同
                        int startIndex = obj1.indexOf("[");
                        int endIndex = obj1.indexOf("]", startIndex);
                        String prix = obj1.substring(startIndex + 1, endIndex);
                        String later = obj2.substring(startIndex + 1, endIndex);
                        //两个日期相同
                        if (prix.equals(later)) {
                            return obj1.compareTo(obj2); // 若相同时，按照默认顺序插入
                        } else {
                            return later.compareTo(prix); // 降序排序
                        }
                    }
                });
        JSONObject data = govGetIncJson(i, day,1);
        //是否为空 数据为空直接返回
        if(data.getBoolean("empty")) {
            return null;
        }
        //不为空获得数据数组
        JSONArray dataArray = data.getJSONArray("data");
        int total = data.getIntValue("total");
        int maxPage = (int)Math.ceil((double) total/dataArray.size());
        //处理第一次获得的数据
        for (int h = 0; h < dataArray.size(); h++) {
            JSONObject item = dataArray.getJSONObject(h);
            String id = item.getString("articleId");
            String title = item.getString("title");
            Timestamp publishDate = (Timestamp)item.getTimestamp("publishDate");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String formattedDate = sdf.format(publishDate);
            String lastKeyword = inTitle(title);
            temp.put("["+formattedDate+"]    "+title+"  ["+lastKeyword+"]",UrlConst.GovDetailUrl+id);
        }

        //获取到后面的数据
        for(int pageNo=2;pageNo<=maxPage;pageNo++){
            data = govGetIncJson(i, day, pageNo);
            if(data.getBoolean("empty")) {
                continue;
            }
            dataArray = data.getJSONArray("data");
            //处理第一次获得的数据
            for (int h = 0; h < dataArray.size(); h++) {
                JSONObject item = dataArray.getJSONObject(h);
                String id = item.getString("articleId");
                String title = item.getString("title");
                Timestamp publishDate = (Timestamp)item.getTimestamp("publishDate");
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String formattedDate = sdf.format(publishDate);
                String lastKeyword = inTitle(title);
                temp.put("["+formattedDate+"]    "+title+"  ["+lastKeyword+"]",UrlConst.GovDetailUrl+id);
            }
        }

        return temp;
    }

    private JSONObject govGetIncJson(int i,int day,int pageNo){
        JSONObject jsonObject = getDetailId.sendPostForGov(UrlConst.GovUrl, "", KeyWordsConst.MykeyCode[i],day,pageNo);
        if (jsonObject==null){
            System.out.println("Gov接口获取失败");
            return null;
        }
        if(!jsonObject.getBoolean("success")){
            System.out.println("Gov当前数据获取失败");
            return null;
        }
        //获取到数据
        JSONObject data = jsonObject.getJSONObject("result").getJSONObject("data");
        return data;
    }

}
